#include "ch32l103.h"
#include "stdint.h"
#include "stdio.h"
#include "DevicesSPI.h"


void vSPI1Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure = {0};
    SPI_InitTypeDef  SPI_InitStructure = {0};

    RCC_PB2PeriphClockCmd(RCC_PB2Periph_GPIOA, ENABLE);
    RCC_PB2PeriphClockCmd(RCC_PB2Periph_GPIOB, ENABLE);
    RCC_PB2PeriphClockCmd(RCC_PB2Periph_SPI1, ENABLE);

    GPIO_SetBits(GPIOB, GPIO_Pin_15);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    SPI1_NSS_SET_HIGH();


    /* SPI0 parameter config */
    SPI_I2S_DeInit(SPI1);
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial = 7;
    SPI_Init(SPI1, &SPI_InitStructure);

    /* SPI enable */
    SPI_Cmd(SPI1, ENABLE);
}

uint8_t ucSPIWriteReadByte(SPI_TypeDef *SPIx, uint8_t ucByte)
{
    uint32_t uiTime;

    for(uiTime = 0; (RESET == (SPIx->STATR & SPI_I2S_FLAG_TXE)) && (uiTime < 10000); ++uiTime);
    SPIx->DATAR = ucByte;

    for(uiTime = 0; (RESET == (SPIx->STATR & SPI_I2S_FLAG_RXNE)) && (uiTime < 10000); ++uiTime);
    ucByte = SPIx->DATAR;

    return ucByte;
}

int8_t cSPIWriteDatas(SPI_TypeDef *SPIx, void *pvBuff, int32_t iLength)
{
    uint8_t *pucBuffer = pvBuff;
    uint32_t uiTime;

    if((pvBuff == NULL) || (iLength < 1))
        return -1;

    while((iLength--) > 0)
    {
        for(uiTime = 0; (RESET == (SPIx->STATR & SPI_I2S_FLAG_TXE)) && (uiTime < 10000); ++uiTime);
        SPIx->DATAR = *pucBuffer++;
    }

    /* 等待发送完毕 */
    for(uiTime = 0; (RESET != (SPIx->STATR & SPI_I2S_FLAG_BSY)) && (uiTime < 20000); ++uiTime);

    /* 执行一次读取，以解除接收溢出状态 */
    for(uiTime = 0; (RESET == (SPIx->STATR & SPI_I2S_FLAG_RXNE)) && (uiTime < 10000); ++uiTime);
    (void)SPIx->DATAR;

    return 0;
}

int8_t cSPIReadDatas(SPI_TypeDef *SPIx, void *pvBuff, int32_t iLength)
{
    uint8_t *pucBuffer = pvBuff;
    uint32_t uiTime;

    if((pvBuff == NULL) || (iLength < 1))
        return -1;

    while((iLength--) > 0)
    {
        SPIx->DATAR = 0xFFFF;

        for(uiTime = 0; (RESET == (SPIx->STATR & SPI_I2S_FLAG_RXNE)) && (uiTime < 10000); ++uiTime);
        *pucBuffer++ = SPIx->DATAR;
    }

    return 0;
}
